﻿
open Microsoft.FSharp.Quotations
open Microsoft.FSharp.Quotations.Patterns
open Microsoft.FSharp.Quotations.DerivedPatterns

let rec describeCode (expr : Expr) =
    match expr with
    // Literal value
    | Int32(i) -> printfn "Integer with value %d" i
    | Double(f) -> printfn "Floating-point with value %f" f
    | String(s) -> printfn "String with value %s" s
    | NewTuple(exps) -> exps |> List.iter (fun exp -> describeCode exp)
    | Var(var) -> printfn "Var: (%s:%s)" var.Name var.Type.Name
    // Calling a method
    | Call(calledOnObject, methInfo, args)
        -> 
        let calledOn = match calledOnObject with
                            | Some(x) -> sprintf "%A" x
                            | None -> "(Called a static method)"
        printfn "Calling method '%s': \n\
                On value: %s \n\
                With args: %A" methInfo.Name calledOn args
    // Lambda expressions
    | Lambda(var, lambdaBody) ->
        printfn
            "Lambda Expression - Introduced value %s with type %s"
            var.Name var.Type.Name
        printfn "Processing body of Lambda Expression..."
        describeCode lambdaBody
    | _ -> printfn "Unknown expression form:\n%A" expr

type Class () =
    member c.M (i:int) = i

let describeArithmatic operation =
    match operation with
    | SpecificCall <@ (+) @> (_,_,[lhs;rhs]) -> printfn "Addition"
    //| SpecificCall <@ @>
    | _ -> failwith "Unkown quotation form."

